package com.zxtc.wh.dao;

/**
 * 读写数据库表的数据访问对象的通用接口
 * 2017年4月8日11:07:22
 *
 * @param <T>
 * @param <ID> 保存在数据库的索引的类型
 */
public interface IObjectDao<T, ID> {

    /**
     * 创建一个新的数据Bean实例并插入到数据库中，如果接口的实现并非更新对象的属性就即时更新到数据库，则此方法意义不大。
     *
     * @return 创建的对象实例，null:创建、插入对象实例失败
     */
    T create();

    /**
     * 插入一个记录到数据库中，
     * 注意：如果某字段是自增长的，则忽略插入的记录中对应的对象字段的值，使用动态生成且自动增长的值代替
     * （其实就是说类似主键的自增长字段的值由数据库定，入参的对应属性不顶用）
     *
     * @return 插入的对象实例，null:插入失败。返回值可能与入参有异，以返回值为准
     * @see #insert(Object)
     */
    T create(T data);

    /**
     * 插入一个记录到数据库中，所有字段值都由入参指定，不做校验
     *
     * @return 插入的对象实例，null:插入失败。返回值可能与入参有异，以返回值为准
     * @see #create(Object)
     */
    T insert(T data);

    /**
     * 创建并插入一条不存在于数据库中的记录(使用{@see #insert}实现),如果数据库中已经保存这条记录，就更新这条记录
     * 判断记录是否存在一般依据表的某个非空不可重复的字段。
     *
     * @return 插入的对象实例，null:创建、插入、读取失败。返回值可能与入参有异，以返回值内为准
     * @see #insert(Object)
     */
    T updateOrCreate(T data);


    /**
     * 在数据库内，是否保存了参数表示的记录
     * 与{@see #getInstance}的区别在于某些情况下当前方法效率更高
     *
     * @param id 数据Bean对象在数据库的主键id
     * @return true：存在，false：不存在，null：数据库读写异常
     */
    Boolean isExists(ID id);


//    /**
//     * 在数据库中查找指定的数据Bean对象
//     *
//     * @param uuid 索引：数据Bean对象的全局唯一标识符
//     * @return 查找到的记录，返回null表示没有此记录或数据库访问异常
//     * @see #getInstance(Object)
//     */
//    T getInstance(String uuid);

    /**
     * 查找指定的数据Bean对象
     *
     * @param id 索引：数据Bean对象在数据库的标识符
     * @return 查找到的记录，返回null表示没有此记录或数据库访问异常
//     * @see #getInstance(String)
     */
    T getInstance(ID id);


    /**
     * 更新某条数据的记录
     * 约定泛型类型的参数表示的数据库记录所属的表有定义主键，且入参的主键字段能无歧义的表示要更新的数据库记录
     *
     * @param data 要修改的记录
     * @return 修改后的记录。返回值与入参可能不同，以返回值为准
     */
    T update(T data);


    /**
     * 读写数据库过程中，try得到的异常、消息都可以（应该）通过调用{@see #onError}记录下来备用
     *
     * @param eMessage 错误消息
     */
    void onError(Exception eMessage);

}
